const { src, dest, parallel, series, watch } = require('gulp')
const loadPlugins = require('gulp-load-plugins')
const plugins = loadPlugins()


// const plugins.sass = require('gulp-sass')
// const plugins.babel = require('gulp-babel')
// const plugins.swig = require('gulp-swig')
// const plugins.imagemin = require('gulp-imagemin')

const del = require('del')
const borwserSync = require('browser-sync')
const bs = borwserSync.create()

const cwd = process.cwd() //返回当前命令行的工作目录（根目录）
let config = {
    //应该有默认值 default
    build: {
        src: 'src',
        dist: 'dist',
        temp: 'temp',
        public: 'public',
        paths: {
            styles: 'src/assets/styles/*scss',
            scripts: 'src/assets/scripts/*.js',
            pages: '*.html',
            images: 'assets/images/**',
            fonts: 'assets/fonts/**',

        }
    }
}
try {
    const loadConfig = require(`${cwd}/pages.config.js`)
    config = Object.assign({}, config, loadConfig) //合并两个对象
} catch (e) {

}

const style = () => {
    return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src })
        //将央视文件也压缩
        .pipe(plugins.sass({ outputStyle: 'expanded' }))
        //将scss文件转换为css文件，下划线开头的文件不会会识别处理
        //参数为将样式文件展开呈现
        .pipe(dest(config.build.temp))
        //通常情况下的热部署处理方式
        .pipe(bs.reload({ stream: true }))

}

const script = () => {
    return src(config.build.paths.scripts, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
        //没有参数不会变更文件内容，babel/preset-env是修改es6特性的插件
        .pipe(dest(config.build.temp))
        //通常情况下的热部署处理方式
        .pipe(bs.reload({ stream: true }))
}

const page = () => {

    //可以使用src/**/*.html 来匹配src下所有子文件夹下的所有html文件
    return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src })
        //解析特定的模板html文件，需要配合模板相关使用。
        .pipe(plugins.swig({ data: config.data }))
        .pipe(dest(config.build.temp))
        //通常情况下的热部署处理方式
        .pipe(bs.reload({ stream: true }))
}

const image = () => {
    return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src })
        .pipe(plugins.imagemin())
        .pipe(dest(config.build.dist))
}

const font = () => {
        return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src })
            .pipe(plugins.imagemin())
            .pipe(dest(config.build.dist))
    }
    //将public中的文件复制到项目中
const extra = () => {
    return src('**', { base: config.build.src, cwd: config.build.public })
        .pipe(dest(config.build.dist))
}

const clean = () => {
    return del([config.build.dist, config.build.temp])
}

const useref = () => {
    return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp }) //需要处理的文件路径
        .pipe(plugins.useref({ searchPath: [config.build.temp, '.'] })) //文件路径的根目录
        .pipe(plugins.if(/\.js$/, plugins.uglify()))
        .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
        .pipe(plugins.if(/\.html$/, plugins.htmlmin({
            collapseWhitespace: true, //去掉所有html中的空白字符，包括换行符
            minifyCSS: true, //将css也压缩
            minifyJS: true, //将js压缩
        })))
        .pipe(dest(config.build.dist))
}

const serve = () => {
        //自动构建方法，使用的gulp中的watch方法，第一个参数为有改动的文件，第二个参数为该文件改动后执行的方法。
        watch(config.build.paths.styles, { cwd: config.build.src }, style)
        watch(config.build.paths.scripts, { cwd: config.build.src }, script)
        watch(config.build.paths.pages, { cwd: config.build.src }, page)
            // watch('src/assets/images/**', image)
            // watch('src/assets/styles/*scss', font)
            // watch('public/**', extra)
            //文件变化后重新渲染浏览器
        watch(
            [
                config.build.paths.images,
                config.build.paths.fonts
            ], { cwd: config.build.src }, bs.reload)
        watch(
            '**', { cwd: config.build.public }, bs.reload)
        bs.init({
            //取消bowserSync的提示，该提示有可能会影响刷新，建议关闭
            notify: false,
            //指定端口
            port: 9999,
            //默认的启动服务器的根目录
            //服务器打开时不同时打开网页
            // open: false,
            //配置需要热部署的文件，可以使用通配符，通常不使用这种方式
            // files: 'dist/**',
            server: {
                //文件同步到服务器的路径
                baseDir: [config.build.temp, config.build.src, config.build.public],
                //在route中的路由配置会优先指定与baseDir
                routes: {
                    '/node_modules': 'node_modules'
                },

            }
        })
    }
    //
const compile = parallel(style, script, page)

//同步执行 parallel   顺序执行 series

//投产任务
const build = series(clean, parallel(series(compile, useref), extra, image, font))

//开发任务
const develop = series(compile, serve)

module.exports = {
    build,
    develop,
    clean,
    useref,

}